package com.alibaba.citrus.cr.mn.order.center.forecastorder.factory;

import com.alibaba.citrus.cr.common.constant.OrderFeaturesKey;
import com.alibaba.citrus.cr.common.enums.ordercenter.FulfillmentPriorityEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.FulfillmentTypeEnum;
import com.alibaba.citrus.cr.common.exception.FunctionException;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.constants.ForecastConstants;
import com.alibaba.citrus.cr.mn.order.center.facade.function.convert.ModifyForecastDTOToForecastOrderBOConvertor;
import com.alibaba.citrus.cr.mn.order.center.forecastorder.convert.CreateForecastDTOToForecastOrderBOConvertor;
import com.alibaba.citrus.cr.mn.order.center.forecastorder.convert.CreateForecastDetailDTOToForecastOrderLineBOConvertor;
import com.alibaba.citrus.cr.mn.order.center.forecastorder.entity.ForecastOrderEntity;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSONObject;
import com.epoch.app.crforecastsales.bo.ForecastOrderBO;
import com.epoch.app.crforecastsales.bo.ForecastOrderLineBO;
import com.epoch.app.mnordercenter.model.dto.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

public class ForecastOrderFactory {

    private static Log log = Log.getLogger(ForecastOrderFactory.class);

    public static List<ForecastOrderEntity> createDraft(ForecastOrderBizBatchCreateRequest saveForecastOrderRequest) {
        List<CreateForecastDTO> createForecastDTOS = saveForecastOrderRequest.getCreateForecastOrderDTOS();

        // 单据列表不能为空，为空直接返回异常
        if (CollectionUtils.isEmpty(createForecastDTOS)) {
            throw new FunctionException("OC-01-001-01-15-001", "单据列表");
        }

        // 兼容老逻辑，将公共入参塞到预报订单主单里
        String businessType = saveForecastOrderRequest.getBusinessType();
        String fromSys = saveForecastOrderRequest.getFromSys();
        String businessUnitCode = saveForecastOrderRequest.getBusinessUnitCode();
        String reqNo = saveForecastOrderRequest.getReqNo();

        List<ForecastOrderEntity> forecastOrderEntityList = new ArrayList<>();
        for (CreateForecastDTO createForecastDTO : createForecastDTOS) {

            // 单据明细不能为空，为空直接返回异常
            List<CreateForecastDetailDTO> createForecastDetailDTOS = createForecastDTO.getForecastOrderDetailDTOS();
            if (CollectionUtils.isEmpty(createForecastDetailDTOS)) {
                throw new FunctionException("OC-01-001-01-15-001", "单据明细");
            }

            // 转换预报订单模型
            ForecastOrderBO forecastOrderBO = CreateForecastDTOToForecastOrderBOConvertor.convert(createForecastDTO);
            forecastOrderBO.setBusinessType(businessType);
            forecastOrderBO.setFromSys(fromSys);
            forecastOrderBO.setBusinessUnitCode(businessUnitCode);
            forecastOrderBO.setReqNo(reqNo);
            if(StringUtils.isBlank(createForecastDTO.getFulfillmentTypeCode())){
                forecastOrderBO.setFulfillmentTypeCode(FulfillmentTypeEnum.EXTERNAL_TO_EXTERNAL.getCode());
            }
            if(StringUtils.isBlank(createForecastDTO.getFulfillmentPriority())){
                forecastOrderBO.setFulfillmentPriority(FulfillmentPriorityEnum.LEVEL100.getCode());
            }
            List<ForecastOrderLineBO> forecastOrderLineSDOList = new ArrayList<>();
            for (CreateForecastDetailDTO createForecastDetailDTO : createForecastDetailDTOS) {
                // 转换预报订单明细模型
                ForecastOrderLineBO forecastOrderLineBO = CreateForecastDetailDTOToForecastOrderLineBOConvertor.convert(createForecastDetailDTO);

                String activityCode = forecastOrderLineBO.getActivityCode();
                if (StringUtils.isNotEmpty(activityCode)) {
                    Map<String, Object> features = new HashMap<>();
                    features.put(ForecastConstants.ACTIVITY_NUMBER, activityCode);
                    forecastOrderLineBO.setFeatures(features);
                }
                forecastOrderLineSDOList.add(forecastOrderLineBO);

                // 兼容老逻辑，从入参单据明细里的发货仓信息塞到主单里
                if (StringUtils.isNotBlank(forecastOrderLineBO.getShippingWarehouseCode())) {
                    forecastOrderBO.setShippingWarehouseCode(forecastOrderLineBO.getShippingWarehouseCode());
                }
                if (StringUtils.isNotBlank(forecastOrderLineBO.getDeliveryFactoryCode())) {
                    forecastOrderBO.setDeliveryFactoryCode(forecastOrderLineBO.getDeliveryFactoryCode());
                }
                if (StringUtils.isNotBlank(forecastOrderLineBO.getStockCode())) {
                    forecastOrderBO.setStockCode(forecastOrderLineBO.getStockCode());
                }
            }

            if (Objects.isNull(forecastOrderBO.getVaildBeginTime())) {
                forecastOrderBO.setVaildBeginTime(new Date());
            }

            forecastOrderBO.setForecastOrderLineBOList(forecastOrderLineSDOList);
            ForecastOrderEntity forecastOrderEntity = ForecastOrderEntity.of(forecastOrderBO);
            forecastOrderEntityList.add(forecastOrderEntity);
        }
        return forecastOrderEntityList;
    }

    public static List<ForecastOrderEntity> createBODraft(List<ForecastOrderBO> forecastOrderBOS) {
        if (CollectionUtils.isEmpty(forecastOrderBOS)) {
            return Lists.newArrayList();
        }

        List<ForecastOrderEntity> forecastOrderEntityList = new ArrayList<>();
        for (ForecastOrderBO forecastOrderBO : forecastOrderBOS) {
            List<ForecastOrderLineBO> forecastOrderLineBOS = forecastOrderBO.getForecastOrderLineBOList();

            if (CollectionUtils.isNotEmpty(forecastOrderLineBOS)) {
                for (ForecastOrderLineBO forecastOrderLineBO : forecastOrderLineBOS) {
                    Map<String, Object> features = new HashMap<>();
                    String activityCode = forecastOrderLineBO.getActivityCode();
                    if (StringUtils.isNotEmpty(activityCode)) {
                        features.put(ForecastConstants.ACTIVITY_NUMBER, activityCode);
                    }
                    String bizFeatures = forecastOrderLineBO.getBizFeatures();
                    if (StringUtils.isNotBlank(bizFeatures)) {
                        JSONObject bizFeaturesJson = JSONObject.parseObject(bizFeatures);
                        Object deadline = bizFeaturesJson.get(OrderFeaturesKey.DEADLINE);
                        if (Objects.nonNull(deadline)) {
                            features.put(OrderFeaturesKey.DEADLINE, DateUtils.toMillisecondByTime((String) deadline));
                        }
                    }
                    forecastOrderLineBO.setFeatures(features);
                    forecastOrderLineBO.setCreatorId(forecastOrderBO.getCreatorId());
                    forecastOrderLineBO.setCreatorName(forecastOrderBO.getCreatorName());
                }
            }
            forecastOrderBO.setVaildBeginTime(forecastOrderBO.getVaildBeginTime() == null ? new Date() : forecastOrderBO.getVaildBeginTime());
            HashMap<String, String> features = new HashMap<>();
            features.put(ForecastConstants.OS, ForecastConstants.ORDER_CENTER);
            forecastOrderBO.setFeatures(features);
            forecastOrderBO.setForecastOrderLineBOList(forecastOrderLineBOS);
            ForecastOrderEntity forecastOrderEntity = ForecastOrderEntity.of(forecastOrderBO);
            forecastOrderEntityList.add(forecastOrderEntity);
        }
        return forecastOrderEntityList;
    }

    public static List<ForecastOrderEntity> createBODraftNotCoverFeature(List<ForecastOrderBO> forecastOrderBOS) {
        List<ForecastOrderEntity> forecastOrderEntityList = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(forecastOrderBOS)) {
            for (ForecastOrderBO forecastOrderBO : forecastOrderBOS) {
                List<ForecastOrderLineBO> forecastOrderLineBOS = forecastOrderBO.getForecastOrderLineBOList();

                if (CollectionUtils.isNotEmpty(forecastOrderLineBOS)) {
                    for (ForecastOrderLineBO forecastOrderLineBO : forecastOrderLineBOS) {
                        String activityCode = forecastOrderLineBO.getActivityCode();
                        if (StringUtils.isNotEmpty(activityCode)) {
                            Map<String, Object> features = new HashMap<>();
                            features.put(ForecastConstants.ACTIVITY_NUMBER, activityCode);
                            forecastOrderLineBO.setFeatures(features);
                        }
                        forecastOrderLineBO.setCreatorId(forecastOrderBO.getCreatorId());
                        forecastOrderLineBO.setCreatorName(forecastOrderBO.getCreatorName());
                    }
                }
                forecastOrderBO.setVaildBeginTime(forecastOrderBO.getVaildBeginTime() == null ? new Date() : forecastOrderBO.getVaildBeginTime());
                if (null != forecastOrderBO.getFeatures()) {
                    forecastOrderBO.getFeatures().put(ForecastConstants.OS,ForecastConstants.ORDER_CENTER);
                } else {
                    HashMap<String,String> features = new HashMap();
                    features.put(ForecastConstants.OS,ForecastConstants.ORDER_CENTER);
                    forecastOrderBO.setFeatures(features);
                }
                forecastOrderBO.setForecastOrderLineBOList(forecastOrderLineBOS);
                ForecastOrderEntity forecastOrderEntity = ForecastOrderEntity.of(forecastOrderBO);
                forecastOrderEntityList.add(forecastOrderEntity);
            }
        }
        return forecastOrderEntityList;
    }

    public static ForecastOrderEntity createModifyEntity(ModifyForecastRequest modifyForecastRequest) {

        ForecastOrderEntity forecastOrderEntity = null;
        if (Objects.nonNull(modifyForecastRequest)&&Objects.nonNull(modifyForecastRequest.getModifyForecastDTO())) {
            ModifyForecastDTO modifyForecastDTO = modifyForecastRequest.getModifyForecastDTO();
            String businessType = modifyForecastRequest.getBusinessType();
            String fromSys = modifyForecastRequest.getFromSys();
            String businessUnitCode = modifyForecastRequest.getBusinessUnitCode();
            ForecastOrderBO forecastOrderBO = ModifyForecastDTOToForecastOrderBOConvertor.convert(modifyForecastDTO);
            forecastOrderBO.setBusinessUnitCode(businessUnitCode);
            forecastOrderBO.setFromSys(fromSys);
            forecastOrderBO.setBusinessType(businessType);
            List<ModifyForecastDetailDTO> modifyForecastDetailDTOS = modifyForecastDTO.getModifyForecastDetailDTOS();
            List<ForecastOrderLineBO> forecastOrderLineBOS=new ArrayList<>();
            if (CollectionUtils.isNotEmpty(modifyForecastDetailDTOS)) {
                for (ModifyForecastDetailDTO modifyForecastDetailDTO : modifyForecastDetailDTOS) {
                    ForecastOrderLineBO forecastOrderLineBO = ModifyForecastDTOToForecastOrderBOConvertor.lineToBO(modifyForecastDetailDTO);
                    String activityCode = modifyForecastDetailDTO.getActivityId();
                    if (StringUtils.isNotEmpty(activityCode)) {
                        Map<String, Object> features = new HashMap<>();
                        features.put(ForecastConstants.ACTIVITY_NUMBER, activityCode);
                        forecastOrderLineBO.setFeatures(features);
                    }
                    forecastOrderLineBOS.add(forecastOrderLineBO);
                    forecastOrderBO.setDeliveryFactoryCode(forecastOrderLineBO.getDeliveryFactoryCode());
                    forecastOrderBO.setShippingWarehouseCode(forecastOrderLineBO.getShippingWarehouseCode());
                    forecastOrderBO.setStockCode(forecastOrderLineBO.getStockCode());
                }
            }
            forecastOrderBO.setVaildBeginTime(forecastOrderBO.getVaildBeginTime() == null ? new Date() : forecastOrderBO.getVaildBeginTime());
            forecastOrderBO.setForecastOrderLineBOList(forecastOrderLineBOS);
            forecastOrderEntity = ForecastOrderEntity.of(forecastOrderBO);
        }
        return forecastOrderEntity;
    }

}
